package gr.upatras.uniexamtimetable;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;


/**
 * An examiner is anyone who is responsible for/connected with an exam
 * 
 * @author spirosag
 */
/**
 * @author spirosag
 *
 */
public class Examiner {

	private String name;

	/*Exam codes of the exams connected to the examiner */
	List<Exam> examCodes = new ArrayList<Exam>();

	/* 
	 * Official Sector of the examiner. Could be different
	 * than the sectors of the exams connected to him
	 */
	private String examinerSector;

	/**
	 * Constructs an object with the given values.
	 * 
	 * @param name the name of the examiner
	 * @param examinerSector the official sector of the examiner.
	 * 						 It could be different from the sector of the exams 
	 * 						 connected to the examiner.
	 * @param examCodes the codes of the exams connected to the examiner 
	 */
	public Examiner(String name, String examinerSector, List<Exam> examCodes) {
		this.name = name;
		this.examCodes = examCodes;
		this.examinerSector = examinerSector;
	}

	/**
	 * Constructs an object with the default values.
	 */
	public Examiner() {
		this.name = "sample examiner";
		this.examinerSector = "Sample sector";
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the codes of the exams connected to the examiner
	 */
	public List<Exam> getExamCodes() {
		return examCodes;
	}

	/**
	 * @param examCodes the codes of the exams connected to the examiner to set
	 */
	public void setExamCodes(List<Exam> examCodes) {
		this.examCodes = examCodes;
	}

	/**
	 * @return the examinerSector
	 */
	public String getExaminerSector() {
		return examinerSector;
	}

	/**
	 * @param examinerSector the examinerSector to set
	 */
	public void setExaminerSector(String examinerSector) {
		this.examinerSector = examinerSector;
	}
	
	/**
	 * Prints all the characteristics of this object.
	 */
	public void printStatus() {
		System.out.printf("Examiner name: %s%n", name);
		if (examinerSector != null) {
			System.out.printf("Examiner sector: %s%n", examinerSector);

		} else {
			System.out.println("The examiner doesn't have a sector.");
		}

		if (examCodes.size() == 0) {
			System.out.println("No exams are connected to the examiner");
		} else {
			System.out.println("Codes of exams connected to the examiner:");
			for (int i = 0; i < examCodes.size(); i++) {
				System.out.println(examCodes.get(i).getCode());
			}
		}
		System.out.println();
	}	

	/**
	 * Returns the values of this object's variables in a single string 
	 * with explanatory labels.
	 * Overrides the <code>java.lang.Object.toString()</code>
	 * 
	 * @return a string with the values of this objects variables 
	 */
	public String toString() {
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.append(String.format("Name: %s, ", name));
		stringBuilder.append(String.format("Sector: %s, ", examinerSector));
		stringBuilder.append("Exam codes of the examiner: ");
		for (int i = 0; i < examCodes.size(); i++) {
			stringBuilder.append(examCodes.get(i).getCode());
			stringBuilder.append(" ,");
		}
		return stringBuilder.toString();
	}

	/**
	 * Exports s <code>List</code> of <code>Examiner</code> objects to a json file
	 * 
	 * @param examiners the {@code List<Examiner>} to be exorted
	 * @param filename the name of the file to export to
	 */
	public static void exportToJson(List<Examiner> examiners, String filename) {

		BufferedWriter writer = null;
		Gson gson = new Gson();

		System.out.printf("Trying to export to %s ...%n", filename);
		
		try {
			writer = new BufferedWriter(new FileWriter(filename));

			/* ugly way to get the type of List<Room> */
			Type collectionType = new TypeToken<List<Examiner>>(){}.getType();
			gson.toJson(examiners, collectionType, writer);
		} catch (IOException e) {
			System.err.printf("Sorry, couldn't export to %s.%n", filename);
			e.printStackTrace();
		} finally {
			try {
				writer.close();
			} catch (IOException e){
				System.err.println("Sorry, couldn't properly close the buffered writer");
				e.printStackTrace();
			}
		}
		
		System.out.printf("Success: %d obcjects were exported.%n", examiners.size());		
	}	

	/* Imports a list of Examiner objects from a json file */
	/**
	 * Imports a <code>List</code> of <code>Examiner</code> objects from a json file
	 * 
	 * @param filename the name of the file to import from
	 * @return a {@code List<Examiner>}
	 */
	public static List<Examiner> importFromJson(String filename) {

		BufferedReader reader = null;
		Gson gson = new Gson();
		List<Examiner> examiners = null;

		System.out.printf("Trying to import from %s ...%n", filename);

		try {
			reader = new BufferedReader(new FileReader(filename));

			/* ugly way to get the type of List<Room> */
			Type collectionType = new TypeToken<List<Examiner>>(){}.getType();
			examiners = gson.fromJson(reader, collectionType);
		} catch (IOException e) {
			System.out.printf("Sorry, couldn't import from %s.%n", filename);
			e.printStackTrace();
		} finally {
			try {
				reader.close();
			} catch (IOException e) {
				System.err.println("Sorry, couldn't close the buffered reader.");
				e.printStackTrace();
			}
		}
		
		System.out.printf("Success: %d obcjects were imported.%n", examiners.size());
		return examiners;
	}
	
}






